#ifndef _DRVRAMFS_T_H_
#define _DRVRAMFS_T_H_

#include <hyper_t.h>
#include <krltime_t.h>
#include <krldevice_t.h>

#define FSOBJ_NM_MAX     (128 - (sizeof (uint_t) * 3))    /* 文件系统对象名字的最大长度 (116 Bytes) */
#define FSBLKS_NBR_MAX   32                               /* 文件系统对象占用逻辑块的数组大小 */

/* 文件系统版本号 */

#define FSVER_MAJ        0                                /* 主版本号 */
#define FSVER_SUB        1                                /* 次版本号 */

/* 块的大小 */

#define FSLOGBLK_SZ      (4 * 1024)                       /* 4KB */
#define FSEMSTOBLK_SZ    (4 * 1024 * 1024)                /* 4MB */
#define FSBLKMAX_NBR     (FSEMSTOBLK_SZ / FSLOGBLK_SZ)    /* 文件系统支持逻辑存储块个数 */

/* 文件系统的对象类型 */

enum FS_OBJ_TYPE
    {
    FS_OBJTYPE_NUL = 0, /* 空类型 */
    FS_OBJTYPE_DIR,     /* 文件夹类型 */
    FS_OBJTYPE_FIL,     /* 文件类型 */
    FS_OBJTYPE_DEL,     /* 删除类型 */
    };

/* 文件系统对象管理头类型 */

enum FS_MH_TYPE
    {
    FS_MHTYPE_NUL = 0, /* 空类型 */
    FS_MHTYPE_DIR,     /* 文件夹类型 */
    FS_MHTYPE_FIL,     /* 文件类型 */
    FS_MHTYPE_DEL,     /* 删除类型 */
    };

/* 逻辑存储块使用状态 */

enum FS_LOGBLK_STUS
    {
    FS_LOGBLK_FREE = 0, /* 逻辑存储块空闲 */
    FS_LOGBLK_USED = 1,  /* 逻辑存储块已被使用 */
    };

/* fsobj (目录或是文件, 目录也是一种特殊的文件) (128 Bytes) */

typedef struct s_FSOBJ
    {
    uint_t       status;                /* 目录状态 */
    uint_t       type;                  /* 目录类型: 空类型、目录类型、文件类型、已删除的类型 */
    uint_t       blkidx;                /* 指向文件数据管理头的块号 (逻辑块块号), 只能按块访问 */
    char_t       name[FSOBJ_NM_MAX];    /* 文件系统对象名字 (最大 116 Bytes) */
    } fsobj_t;

/* 超级块数据结构 */

typedef struct s_FSSUPBLK
    {
    spinlock_t lock;        /* 超级块在内存中使用的自旋锁 */
    uint_t     flag;        /* 标志 */
    uint_t     status;      /* 状态 */
    uint_t     magic;       /* 文件系统标识 */
    uint_t     majver;      /* 文件系统主版本号 */
    uint_t     subver;      /* 文件系统子版本号 */
    size_t     strucsz;     /* 数据结构本身大小 */
    size_t     supblkstart; /* 超级块开始的逻辑块 */
    uint_t     supblknbr;   /* 超级块占用的逻辑块个数 */
    uint_t     bmpblkstart; /* 位图的开始逻辑块 */
    uint_t     bmpblknbr;   /* 位图占用的逻辑块个数 */
    size_t     logblksz;    /* 逻辑块大小 */
    uint_t     fsallblknbr; /* 文件系统逻辑存储块总数量 */
    fsobj_t    rootdir;     /* 保存根目录的名称和指向管理根目录数据的文件数据管理头的块号 */
    } fssupblk_t;


/* 文件系统文件管理头类型 */

enum FSMH_TYPE
    {
    FSMH_TYPE_NUL = 0,    /* 文件管理头 数据空类型 */
    FSMH_TYPE_DIR,        /* 文件管理头 目录类型 */
    FSMH_TYPE_FIL,        /* 文件管理头 文件类型 */
    FSMH_TYPE_DEL,        /* 文件管理头 删除类型 */
    };

/* 文件系统对象的逻辑块信息 (如占用10~15,则分别为: 10 和 5) */

typedef struct s_FSOBJLLOGBLK
    {
    uint_t      blkstart;    /* 开始的逻辑存储序号 */
    uint_t      blknbr;      /* 逻辑存储块的块数 (从 blkstart 开始的连续逻辑块块数) */
    } fsobjlogblk_t;

/* 文件系统对象管理头结构体 (存放在文件对象所在的第一个逻辑块的首个512Byte空间) */

typedef struct s_FSOBJMH
    {
    uint_t        status;                 /* 对象状态 */
    uint_t        type;                   /* 对象类型 */
    uint_t        flag;                   /* 标志 */
    uint_t        sfblkidx;               /* 对象管理头自身所在的逻辑块序号 */
    uint_t        access;                 /* 对象访问权限 */
    ktime_t       newtime;                /* 对象创建时间 */
    ktime_t       acstime;                /* 对象访问时间 */
    ktime_t       modtime;                /* 对象修改时间 */
    uint_t        blknbr;                 /* 对象占用逻辑块个数 */
    uint_t        size;                   /* 对象大小 */
    uint_t        firstblkoffset;         /* 文件数据在第一块逻辑块中的偏移 */ 
    uint_t        endblkoffset;           /* 文件数据在最后块逻辑块中的偏移 */
    uint_t        curwrtblkidx;           /* 文件数据当前将要写入的逻辑块 */
    uint_t        curwrtblkoffset;        /* 文件数据在将要写入的逻辑块中的偏移 */
    fsobjlogblk_t logblk[FSBLKS_NBR_MAX]; /* 文件占用逻辑块的数组 */
    uint_t        linkprevmh;             /* 指向上一个文件管理头的逻辑块 (logblk数组不够用时再分配) */
    uint_t        linknextmh;             /* 指向下一个文件管理头的逻辑块 (logblk数组不够用时再分配) */
    } fsobjmh_t;

/* 模拟存储介质数据结构 */

typedef struct s_FSEMSTO
    {
    spinlock_t lock;      /* 自旋锁 */
    list_t     list;      /* 链表 */
    uint_t     flag;      /* 标志 */
    uint_t     status;    /* 状态 */
    void *     addrstart; /* 模拟存储介质的内存块开始地址 */
    size_t     size;      /* 内存块大小 */
    } fsemsto_t;

#endif

